home *** CD-ROM | disk | FTP | other *** search
- *
- * 6581.asm - SID-Emulation
- *
- * Copyright (C) 1994-1995 by Christian Bauer
- *
-
- *
- * Anmerkungen:
- * ------------
- *
- * Funktionsprinzip:
- * - Es bestehen vier Möglichkeiten zur SID-Emulation, die über das
- * Flag UseSIDCard ausgewählt werden: Keine Emulation (d.h. kein Ton),
- * die Verwendung der SID-Karte, die "6581sid.library" und die
- * "playsid.library"
- *
- * SID-Karte:
- * - Die SID-Karte enthält einen echten C64-SID, der im Adreßraum
- * $a00001-$a00039 (Register an den ungeraden Adressen) eingeblendet
- * ist (z.B. auf einer Zorro-II-Karte)
- * - Wegen Timing-Problemen mit der Karte werden Lesezugriffe aus
- * SID-Registern nur simuliert
- * - Die Power-LED ist mit dem Reset-Eingang des SID verbunden,
- * d.h. ein kurzes Aus- und Einschalten der LED setzt den SID
- * zurück
- *
- * PlaySID:
- * - Da die playsid.library keinen Befehl zum direkten Setzen von SID-
- * Registern hat, wird ein Trick angewendet: Es wird ein Dummy-Modul
- * installiert, dessen Play-Routine nur die Aufgabe hat, ein einziges
- * SID-Register zu setzen. Schreibt der Prozessor in ein SID-Register,
- * werden Registernummer und Wert in die Play-Routine im C64-RAM der
- * playsid.library geschrieben und über ForwardSong ein Aufruf der
- * Play-Routine erzwungen
- *
-
- MACHINE 68020
-
- INCLUDE "exec/types.i"
- INCLUDE "exec/macros.i"
- INCLUDE "exec/nodes.i"
- INCLUDE "libraries/playsidbase.i"
- INCLUDE "libraries/playsid_lib.i"
- INCLUDE "hardware/intbits.i"
-
- XREF _SysBase
- XREF _GfxBase
- XREF _SID6581Base
- XREF _PlaySidBase
-
- XREF Random
-
- XDEF Reset6581
- XDEF ReadFrom6581
- XDEF WriteTo6581
- XDEF _PauseSound
- XDEF _ResumeSound
- XDEF _GetSIDDump
- XDEF InitSID
- XDEF ExitSID
- XDEF ChangedSIDPrefs
- XDEF SIDType ;Prefs
-
- SECTION "text",CODE
-
- *
- * Definitionen
- *
-
- ; SIDType
- SIDTYPE_OFF = 0 ;Audio-Ausgabe aus
- SIDTYPE_CARD = 1 ;SID-Karte
- SIDTYPE_A64 = 2 ;6581sid.library
- SIDTYPE_PSID = 3 ;playsid.library
-
- ; 6581sid.library
- SID_AllocSID = -30
- SID_FreeSID = -36
- SID_Interrupt = -42
- SID_Initialize = -48
- SID_ResetSID = -54
- SID_IRQOnOff = -60
- SID_ReadReg = -72
- SID_WriteReg = -78
-
- ; SID Handle Struktur
- sid_Enabled = 4
- sid_Filter = 5
- sid_60Hz = 6
- sid_RingQual = 7
- sid_SyncQual = 8
- sid_ADSRQual = 13
- sid_IRQRate = 18
-
-
- **
- ** SID-Emulation starten
- **
-
- InitSID move.w SIDType,CurrentSIDType
- bsr OpenSID
- st.b SIDInited
- rts
-
-
- **
- ** SID-Emulation beenden
- **
-
- ExitSID tst.b SIDInited
- beq 1$
- bsr CloseSID
- 1$ rts
-
-
- **
- ** SID-Einstellungen wurde verändert
- **
-
- ; Schließen und neu öffnen, wenn sich die Einstellungen geändert haben
- ChangedSIDPrefs move.w SIDType,d0
- cmp.w CurrentSIDType,d0
- beq 1$
- bsr CloseSID
- move.w SIDType,CurrentSIDType
- bsr OpenSID
- 1$ rts
-
-
- *
- * Alles für SID-Emulation mit CurrentSIDType vorbereiten
- *
-
- OpenSID cmp.w #SIDTYPE_A64,CurrentSIDType
- beq OpenA64
- cmp.w #SIDTYPE_PSID,CurrentSIDType
- beq OpenPSID
- rts
-
- OpenA64 move.l _SID6581Base,d0 ;6581sid.library offen?
- beq 1$
-
- move.l a6,-(sp) ;Ja, SIDHandle holen
- move.l d0,a6
- jsr SID_AllocSID(a6)
- move.l d0,SIDHandle
- beq 2$
-
- move.l d0,a1 ;Parameter setzen
- st.b sid_Enabled(a1)
- clr.b sid_Filter(a1)
- st.b sid_60Hz(a1)
- move.b #48,sid_RingQual(a1)
- move.b #48,sid_SyncQual(a1)
- move.b #48,sid_ADSRQual(a1)
- move.w #60,sid_IRQRate(a1)
- jsr SID_Initialize(a6)
-
- move.l SIDHandle,a1 ;SID anschalten
- moveq #0,d0
- jsr SID_IRQOnOff(a6)
-
- move.l _SysBase,a6 ;VBI einrichten
- lea VBInterrupt,a1
- moveq #INTB_VERTB,d0
- JSRLIB AddIntServer
-
- 2$ move.l (sp)+,a6
- 1$ rts
-
- OpenPSID clr.b PSIDOpened
-
- move.l _PlaySidBase,d0 ;playsid.library offen?
- beq 1$
-
- move.l a6,-(sp)
- move.l d0,a6 ;Ja, Resourcen belegen
- jsr _LVOAllocEmulResource(a6)
- tst.l d0
- bne 2$
-
- lea PSIDHeader,a0 ;"Modul" setzen
- move.l a0,a1
- move.l #PSIDEnd-PSIDHeader,d0
- jsr _LVOSetModule(a6)
-
- moveq #1,d0 ;Und starten
- jsr _LVOStartSong(a6)
- tst.l d0
- beq 3$
-
- jsr _LVOFreeEmulResource(a6) ;Nicht gelungen
- bra 2$
-
- 3$ bset #1,$bfe001 ;Filter aus
- st.b PSIDOpened
-
- 2$ move.l (sp)+,a6
- 1$ rts
-
-
- *
- * SID-Emulation mit CurrentSIDType beenden
- *
-
- CloseSID cmp.w #SIDTYPE_A64,CurrentSIDType
- beq CloseA64
- cmp.w #SIDTYPE_PSID,CurrentSIDType
- beq ClosePSID
- rts
-
- CloseA64 move.l SIDHandle,d0
- beq 1$
-
- move.l a6,-(sp)
- move.l _SID6581Base,a6 ;SID abschalten
- move.l d0,a1
- moveq #-1,d0
- jsr SID_IRQOnOff(a6)
-
- move.l _SysBase,a6 ;VBI entfernen
- lea VBInterrupt,a1
- moveq #INTB_VERTB,d0
- JSRLIB RemIntServer
-
- move.l _SID6581Base,a6
- move.l SIDHandle,a1 ;Und SIDHandle freigeben
- jsr SID_FreeSID(a6)
- clr.l SIDHandle
- move.l (sp)+,a6
- 1$ rts
-
- ClosePSID tst.b PSIDOpened
- beq 1$
-
- move.l a6,-(sp)
- move.l _PlaySidBase,a6
- jsr _LVOStopSong(a6) ;Alles freigeben
- jsr _LVOFreeEmulResource(a6)
- bclr #1,$bfe001 ;Filter an
- clr.b PSIDOpened
- move.l (sp)+,a6
- 1$ rts
-
-
- *
- * Interrupt-Routine
- * a1: SIDHandle
- *
-
- IntProc move.l _SID6581Base,a6
- jsr SID_Interrupt(a6)
- moveq #0,d0 ;Nächsten Server aufrufen
- rts
-
-
- **
- ** Sound stummschalten
- **
-
- _PauseSound cmp.w #SIDTYPE_A64,CurrentSIDType
- beq PauseA64
- cmp.w #SIDTYPE_PSID,CurrentSIDType
- beq PausePSID
- rts
-
- PauseA64 move.l SIDHandle,d0
- beq 1$
- move.l a6,-(sp)
- move.l _SID6581Base,a6
- move.l d0,a1
- moveq #-1,d0
- jsr SID_IRQOnOff(a6)
- move.l (sp)+,a6
- 1$ rts
-
- PausePSID tst.b PSIDOpened
- beq 1$
- move.l a6,-(sp)
- move.l _PlaySidBase,a6
- jsr _LVOPauseSong(a6)
- move.l (sp)+,a6
- 1$ rts
-
-
- **
- ** Sound wieder laut machen
- **
-
- _ResumeSound cmp.w #SIDTYPE_A64,CurrentSIDType
- beq ResumeA64
- cmp.w #SIDTYPE_PSID,CurrentSIDType
- beq ResumePSID
- rts
-
- ResumeA64 move.l SIDHandle,d0
- beq 1$
- move.l a6,-(sp)
- move.l _SID6581Base,a6
- move.l d0,a1
- moveq #0,d0
- jsr SID_IRQOnOff(a6)
- move.l (sp)+,a6
- 1$ rts
-
- ResumePSID tst.b PSIDOpened
- beq 1$
- move.l a6,-(sp)
- move.l _PlaySidBase,a6
- jsr _LVOContinueSong(a6)
- move.l (sp)+,a6
- 1$ rts
-
-
- **
- ** SID zurücksetzen
- **
-
- Reset6581 lea Registers,a0
- moveq #32/4-1,d0
- 1$ clr.l (a0)+
- dbra d0,1$
-
- cmp.w #SIDTYPE_CARD,CurrentSIDType
- beq ResetCard
- cmp.w #SIDTYPE_A64,CurrentSIDType
- beq ResetA64
- cmp.w #SIDTYPE_PSID,CurrentSIDType
- beq ResetPSID
- rts
-
- ResetCard move.l a6,-(sp)
- move.l _GfxBase,a6
- JSRLIB WaitTOF
- bset #1,$bfe001 ;LED aus
- JSRLIB WaitTOF
- bclr #1,$bfe001 ;LED an
- move.l (sp)+,a6
- rts
-
- ResetA64 move.l SIDHandle,d0
- beq 1$
- move.l a6,-(sp)
- move.l _SID6581Base,a6
- move.l d0,a1
- jsr SID_ResetSID(a6)
- move.l (sp)+,a6
- 1$ rts
-
- ResetPSID tst.b PSIDOpened
- beq 1$
- move.l a6,-(sp)
- move.l _PlaySidBase,a6
- jsr _LVOStopSong(a6)
- moveq #1,d0
- jsr _LVOStartSong(a6)
- move.l (sp)+,a6
- 1$ rts
-
-
- **
- ** SID-Status in Datenstruktur schreiben
- **
-
- _GetSIDDump move.l 4(sp),a1
- lea Registers,a0
-
- moveq #24,d0 ;freq_lo_1 bis mode_vol
- 1$ move.b (a0)+,(a1)+
- dbra d0,1$
-
- st (a1)+ ;pot_x
- st (a1)+ ;pot_y
- clr.b (a1)+ ;osc_3
- clr.b (a1) ;env_3
- rts
-
-
- **
- ** Aus einem SID-Register lesen
- ** d0.w: Registernummer ($00-$1f)
- ** Rückgabe: d0.b: Byte
- **
- ** Darf das obere Wort von d0 und d1 nicht verändern!
- **
-
- ReadFrom6581 cmp.b #$19,d0
- beq ReadFF
- cmp.b #$1a,d0
- beq ReadFF
- cmp.b #$1b,d0
- beq ReadRnd
- moveq #0,d0
- rts
-
- ReadFF move.b #-1,d0 ;A/D-Wandler
- rts
-
- ReadRnd jsr Random
- moveq #0,d1 ;MSW löschen
- rts
-
-
- **
- ** In ein SID-Register schreiben
- ** d0.w: Registernummer ($00-$1f)
- ** d1.b: Byte
- **
- ** Darf das obere Wort von d0 und d1 nicht verändern!
- **
-
- WriteTo6581 move.b d1,(Registers,d0.w)
- cmp.w #SIDTYPE_CARD,CurrentSIDType
- beq WriteCard
- cmp.w #SIDTYPE_A64,CurrentSIDType
- beq WriteA64
- cmp.w #SIDTYPE_PSID,CurrentSIDType
- beq WritePSID
- rts
-
- WriteCard lea $a00001,a0 ;SID-Karte
- move.b d1,(a0,d0.w*2)
- rts
-
- WriteA64 tst.l SIDHandle
- beq 1$
- move.l a6,-(sp)
- move.l _SID6581Base,a6
- move.l SIDHandle,a1 ;d0: Regnum, d1: Byte
- jsr SID_WriteReg(a6)
- move.l (sp)+,a6
- moveq #0,d0
- moveq #0,d1
- 1$ rts
-
- WritePSID tst.b PSIDOpened
- beq 1$
- move.l a6,-(sp)
- move.l _PlaySidBase,a6
- move.l $15a(a6),a0 ;Code im C64-RAM der playsid.library ändern
- move.b d0,$1004(a0)
- move.b d1,$1002(a0)
- moveq #1,d0 ;Aufruf der Play-Routine erzwingen
- jsr _LVOForwardSong(a6)
- move.l (sp)+,a6
- moveq #0,d0
- moveq #0,d1
- 1$ rts
-
-
- **
- ** SID-Register (nur als Backup für SAM und Snapshots)
- **
-
- Registers ds.b 32
-
-
- **
- ** Konstanten
- **
-
- IntName dc.b "Frodo SID VBI",0
-
-
- **
- ** Initialisierte Daten
- **
-
- SECTION "DATA",DATA
-
- VBInterrupt dc.l 0,0
- dc.b NT_INTERRUPT,0
- dc.l IntName
- SIDHandle dc.l 0 ;Handle für die 6581sid.library und Flag, daß sie verfügbar ist
- dc.l IntProc
-
- SIDType dc.w 0 ;Prefs: Art der SID-Emulation
-
- PSIDHeader dc.b "PSID" ;Dummy-Modul-Header für playsid.library
- dc.w 2
- dc.w PSIDHeaderEnd-PSIDHeader
- dc.w $1000 ;Load
- dc.w $1000 ;Init
- dc.w $1001 ;Play
- dc.w 1
- dc.w 1
- dc.l 0
- ds.b HEADERINFO_SIZE
- ds.b HEADERINFO_SIZE
- ds.b HEADERINFO_SIZE
- dc.w 0
- dc.l 0
- PSIDHeaderEnd
- ;Init:
- dc.b $60 ; rts
-
- ;Play:
- dc.b $a9,0 ; lda #xx
- dc.b $8d,0,$d4 ; sta $d4xx
- dc.b $60 ; rts
- PSIDEnd
-
-
- **
- ** Nicht initialisierte Daten
- **
-
- SECTION "BSS",BSS
-
- CurrentSIDType ds.w 1 ;Augenblicklicher SID-Typ
-
- SIDInited ds.b 1 ;Flag: InitSID wurde aufgerufen
- PSIDOpened ds.b 1 ;Flag: playsid.library ist initialisiert
-
- END
-